using Gtk;
using System;

namespace Serpis
{
	[System.ComponentModel.ToolboxItem(true)]
	public abstract partial class EntityListView : Gtk.Bin, IListView
	{
		protected Type modelType;
		protected Type viewType;
		
		public EntityListView (Type modelType, Type viewType)
		{
			this.Build ();
			
			this.viewType= viewType;
			this.modelType= modelType;
			
			label.LabelProp= "Nombre";
		}
		
		protected Entry entry {get {return pEntry;}}
		protected HBox hBox {get {return pHBoxFilter;}}
		protected Label label {get {return pLabel;}}
		protected MiTreeView miTreeView {get{return pMiTreeView;}}
		
		protected abstract string getSql();
		
		public virtual object getId() {
			long id= Convert.ToInt64(miTreeView.GetValue(0));
			return id;
		}
		
		protected void init() {
			string sql = getSql();
			miTreeView.Init(AppDbConnection.Instance.SessionFactory, sql, modelType);
			
			miTreeView.Changed += delegate {
				raiseChanged();
			};		
		}
		
		public virtual void Refresh()
		{
			string sql = getSql();
			miTreeView.Refresh(sql);
		}
		
		public virtual bool HasSelected {
			get {return miTreeView.HasSelected;}
		}
		
		
		protected virtual void raiseChanged()
		{
			if (Changed != null)
				Changed(this, EventArgs.Empty);
		}
		
		public event EventHandler Changed;
		
		public virtual void New() {
			IPersister persister = PersisterFactory.NewPersister(modelType);
			
			object model= Activator.CreateInstance(modelType);
			show(model, persister);
		}
		
		public virtual void Edit()
		{
			IPersister persister = PersisterFactory.NewPersister(modelType);
			
			object model= persister.Load(modelType, getId());
			
			show(model, persister);
		}
		
		protected virtual void show(object model, IPersister persister) {
			IEntityView view = (IEntityView)Activator.CreateInstance(viewType);
			
			Controller controller = new Controller(model, view);
			controller.Refresh();
			
			view.SaveAction.Activated += delegate {
				controller.Update();
				persister.Save(model);
				miTreeView.Refresh();
				view.Destroy();
			};
		}
		
		public virtual void Delete() {
			MessageDialog messageDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Question, ButtonsType.YesNo, "¿Quiere eliminar el elemento seleccionado?");
			messageDialog.Title = modelType.GetLabel();
			int response = messageDialog.Run();
			messageDialog.Destroy();
			if (response != (int)ResponseType.Yes)
				return;
			
			IPersister persister = new Persister();
			persister.Delete(modelType, persister.Load(modelType, getId()));
			miTreeView.Refresh();
		}
	}
}